home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / TUTORIAL / 1778A.ZIP / CHAP12.TXT < prev    next >
Text File  |  1989-11-10  |  24KB  |  530 lines

  1.  
  2.  
  3.  
  4.  
  5.                                                    Chapter 12
  6.                                            DYNAMIC ALLOCATION
  7.  
  8.  
  9.  
  10. WHAT IS DYNAMIC ALLOCATION?
  11. ____________________________________________________________
  12.  
  13. Dynamic allocation is very intimidating to a    =============
  14. person the first time he comes across it, but     DYNLIST.C
  15. that need not be.  Simply relax and read this   =============
  16. chapter carefully and you will have a good
  17. grounding in a very valuable programming
  18. resource.  All of the variables in every program up to this
  19. point have been static variables as far as we are concerned. 
  20. (Actually, some of them have been automatic and were
  21. dynamically allocated for you by the system, but it was
  22. transparent to you.)  In this chapter, we will study some
  23. dynamically allocated variables.  They are variables that do
  24. not exist when the program is loaded, but are created
  25. dynamically as they are needed.  It is possible, using these
  26. techniques, to create as many variables as needed, use them,
  27. and deallocate their space for use by other variables.  As
  28. usual, the best teacher is an example, so examine the program
  29. named DYNLIST.C.
  30.  
  31. We begin by defining a named structure animal with a few
  32. fields pertaining to dogs.  We do not define any variables of
  33. this type, only three pointers.  If you search through the
  34. remainder of the program, you will find no variables defined
  35. so we have nothing to store data in.  All we have to work with
  36. are three pointers, each of which point to the defined
  37. structure.  In order to do anything, we need some variables,
  38. so we will create some dynamically.
  39.  
  40.  
  41.  
  42. DYNAMIC VARIABLE CREATION
  43. ____________________________________________________________
  44.  
  45. The statement in line 14, which assigns something to the
  46. pointer pet1 will create a dynamic structure containing three
  47. variables.  The heart of the statement is the malloc()
  48. function buried in the middle of the statement.  This is a
  49. memory allocate function that needs the other things to
  50. completely define it.  The malloc() function, by default, will
  51. allocate a piece of memory on a heap that is "n" characters
  52. in length and will be of type character.  The "n" must be
  53. specified as the only argument to the function.  We will
  54. discuss "n" shortly, but first we need to define a heap.
  55.  
  56.  
  57.  
  58.  
  59.                                                     Page 12-1
  60.  
  61.                               Chapter 12 - Dynamic Allocation
  62.  
  63. WHAT IS A HEAP?
  64. ____________________________________________________________
  65.  
  66. Every compiler has a set of limitations on it as to how big
  67. the executable file can be, how many variables can be used,
  68. how long the source file can be, etc.  One limitation placed
  69. on users by most MS-DOS C compilers is a limit of 64K for the
  70. executable code if you happen to be in the small memory model. 
  71. This is because the IBM-PC uses a microprocessor with a 64K
  72. segment size, and it requires special calls to use data
  73. outside of a single segment.  In order to keep the program
  74. small and efficient, these calls are not used in some MS-DOS
  75. implementations of C, and the memory space is limited but
  76. still adequate for most programs. 
  77.  
  78. A heap is an area outside of this 64K boundary which can be
  79. accessed by the program to store data and variables.  The data
  80. and variables are put on the heap by the system as calls to
  81. malloc() are made.  The system keeps track of where the data
  82. is stored.  Data and variables can be deallocated as desired
  83. leading to holes in the heap.  The system knows where the
  84. holes are and will use them for additional data storage as
  85. more malloc() calls are made.  The structure of the heap is
  86. therefore a very dynamic entity, changing constantly.
  87.  
  88.  
  89. MORE ABOUT SEGMENTS
  90. ____________________________________________________________
  91.  
  92. Most C compilers give the user a choice of memory models to
  93. use.  The user has a choice of using a model with a 64K
  94. limitation for either program or data leading to a small fast
  95. program or selecting a 640K limitation and requiring longer
  96. address calls leading to less efficient addressing.  Using the
  97. larger address space requires inter segment addressing,
  98. resulting in the slightly slower running time.  The time is
  99. probably insignificant in most programs, but there are other
  100. considerations.
  101.  
  102. If a program uses no more than 64K bytes for the total of its
  103. code and memory and if it doesn't use a stack, it can be made
  104. into a .COM file.  Since a .COM file is already in a memory
  105. image format, it can be loaded very quickly whereas a file in
  106. an .EXE format must have its addresses relocated as it is
  107. loaded.  Therefore a tiny memory model can generate a program
  108. that loads faster than one generated with a larger memory
  109. model.  Don't let this worry you, it is a fine point that few
  110. programmers worry about.
  111.  
  112. Using dynamic allocation, it is possible to store the data on
  113. the heap and that may be enough to allow you to use the small
  114. memory model.  Of course, you wouldn't store local variables
  115. such as counters and indexes on the heap, only very large
  116. arrays or structures.
  117.  
  118.                                                     Page 12-2
  119.  
  120.                               Chapter 12 - Dynamic Allocation
  121.  
  122.  
  123. Even more important than the need to stay within the small
  124. memory model is the need to stay within the computer.  If you
  125. had a program that used several large data storage areas, but
  126. not at the same time, you could load one block storing it
  127. dynamically, then get rid of it and reuse the space for the
  128. next large block of data.  Dynamically storing each block of
  129. data in succession, and using the same storage for each block
  130. may allow you to run your entire program in the computer
  131. without breaking it up into smaller programs. 
  132.  
  133.  
  134.  
  135. BACK TO THE MALLOC FUNCTION
  136. ____________________________________________________________
  137.  
  138. Hopefully the above description of the heap and the overall
  139. plan for dynamic allocation helped you to understand what we
  140. are doing with the malloc() function.  It simply asks the
  141. system for a block of memory of the size specified, and gets
  142. the block with the pointer pointing to the first element of
  143. the block.  The only argument in the parentheses is the size
  144. of the block desired and in our present case, we desire a
  145. block that will hold one of the structures we defined at the
  146. beginning of the program.  The sizeof operator is new, new to
  147. us at least.  It returns the size in bytes of the argument
  148. within its parentheses.  It therefore, returns the size of the
  149. structure named animal, in bytes, and that number is sent to
  150. the system with the malloc() call.  At the completion of that
  151. call, we have a block on the heap allocated to us, with pet1
  152. pointing to the block of data.
  153.  
  154.  
  155.  
  156. WHAT IS A CAST?
  157. ____________________________________________________________
  158.  
  159. We still have a funny looking construct at the beginning of
  160. the malloc() function call.  That is called a cast.  The
  161. malloc() function returns a block with the pointer pointing
  162. to it being a pointer to type void by default.  You really
  163. cannot use a pointer to void, so it must be changed to some
  164. other type.  You can define the pointer type with the
  165. construct given on the example line.  In this case we want the
  166. pointer to point to a structure of type animal, so we tell the
  167. compiler with this strange looking construct.  Even if you
  168. omit the cast, most compilers will return a pointer correctly,
  169. give you a warning, and go on to produce a working program. 
  170. It is better programming practice to provide the compiler with
  171. the cast to prevent getting the warning message.  The data
  172. space of the computer is depicted graphically by figure 12-1.
  173.  
  174.  
  175.  
  176.  
  177.                                                     Page 12-3
  178.  
  179.                               Chapter 12 - Dynamic Allocation
  180.  
  181. USING THE DYNAMICALLY ALLOCATED STRUCTURE
  182. ____________________________________________________________
  183.  
  184. If you remember our studies of structures and pointers, you
  185. will recall that if we have a structure with a pointer
  186. pointing to it, we can access any of the variables within the
  187. structure.  In lines 15 through 17 of the program, we assign
  188. some silly data to the structure for illustration.  It should
  189. come as no surprise to you that these assignment statements
  190. look just like assignments to statically defined variables. 
  191. Figure 12-2 illustrates the state of the data space at this
  192. point in the program execution.
  193.  
  194. In the next statement, we assign the value of pet1 to pet2
  195. also.  This creates no new data, we simply have two pointers
  196. to the same object.  Since pet2 is pointing to the structure
  197. we created above, pet1 can be reused to get another
  198. dynamically allocated structure which is just what we do next. 
  199. Keep in mind that pet2 could have just as easily been used for
  200. the new allocation.  The new structure is filled with silly
  201. data for illustration.
  202.  
  203. Finally, we allocate another block on the heap using the
  204. pointer pet3, and fill its block with illustrative data. 
  205. Figure 12-3 illustrates the condition of the data space
  206. following execution of line 29 of the program.
  207.  
  208. Printing the data out should pose no problem to you since
  209. there is nothing new in the three print statements.  It is
  210. left for you to study.
  211.  
  212. Even though it is not illustrated in this tutorial, you can
  213. dynamically allocate and use simple variables such as a single
  214. char type variable.  This should be discouraged however since
  215. it is very inefficient.
  216.  
  217.  
  218. GETTING RID OF THE DYNAMICALLY ALLOCATED DATA
  219. ____________________________________________________________
  220.  
  221. Another new function is used to get rid of the data and free
  222. up the space on the heap for reuse, the function free().  To
  223. use it, you simply call it with the pointer to the block as
  224. the only argument, and the block is deallocated.
  225.  
  226. In order to illustrate another aspect of the dynamic
  227. allocation and deallocation of data, an additional step is
  228. included in the program on your monitor.  The pointer pet1 is
  229. assigned the value of pet3 in line 42.  In doing this, the
  230. block that pet1 was pointing to is effectively lost since
  231. there is no pointer that is now pointing to that block.  It
  232. can therefore never again be referred to, changed, or disposed
  233. of.  That memory, which is a block on the heap, is wasted from
  234. this point on.  This is not something that you would ever
  235.  
  236.                                                     Page 12-4
  237.  
  238.                               Chapter 12 - Dynamic Allocation
  239.  
  240. purposely do in a program.  It is only done here for
  241. illustration.
  242.  
  243. The first free() function call removes the block of data that
  244. pet1 and pet3 were pointing to, and the second free() call
  245. removes the block of data that pet2 was pointing to.  We
  246. therefore have lost access to all of our data generated
  247. earlier.  There is still one block of data that is on the heap
  248. but there is no pointer to it since we lost the address to it. 
  249. Figure 12-4 illustrates the data space as it now appears. 
  250. Trying to free the data pointed to by pet1 would result in an
  251. error because it has already been freed by the use of pet3. 
  252. There is no need to worry, when we return to DOS, the entire
  253. heap will be disposed of with no regard to what we have put
  254. on it.  The point does need to made that, if you lose a
  255. pointer to a block of the heap, it forever removes that block
  256. of data storage from our use and we may need that storage
  257. later.
  258.  
  259. Compile and run the program to see if it does what you think
  260. it should do based on this discussion.
  261.  
  262.  
  263. THAT WAS A LOT OF DISCUSSION
  264. ____________________________________________________________
  265.  
  266. It took six pages to get through the discussion of the last
  267. program but it was time well spent.  It should be somewhat
  268. exciting to you to know that there is nothing else to learn
  269. about dynamic allocation, the last six pages covered it all. 
  270. Of course, there is a lot to learn about the technique of
  271. using dynamic allocation, and for that reason, there are two
  272. more example programs to study.  But the fact remains, there
  273. is nothing more to learn about dynamic allocation than what
  274. was given so far in this chapter.
  275.  
  276.  
  277. AN ARRAY OF POINTERS
  278. ____________________________________________________________
  279.  
  280. Load and display the file BIGDYNL.C for         =============
  281. another example of dynamic allocation.  This      BIGDYNL.C
  282. program is very similar to the last one since   =============
  283. we use the same structure, but this time we
  284. define an array of pointers to illustrate the
  285. means by which you could build a large database using an array
  286. of pointers rather than a single pointer to each element.  To
  287. keep it simple we define 12 elements in the array and another
  288. working pointer named point.
  289.  
  290. The *pet[12] is new to you so a few words would be in order. 
  291. What we have defined is an array of 12 pointers, the first
  292. being pet[0], and the last pet[11].  Actually, since an array
  293. is itself a pointer, the name pet by itself is a pointer to
  294.  
  295.                                                     Page 12-5
  296.  
  297.                               Chapter 12 - Dynamic Allocation
  298.  
  299. a pointer.  This is valid in C, and in fact you can go farther
  300. if needed but you will get quickly confused.  I know of no
  301. limit as to how many levels of pointing are possible, so a
  302. definition such as int ****pt; is legal as a pointer to a
  303. pointer to a pointer to a pointer to an integer type variable,
  304. if I counted right.  Such usage is discouraged until you gain
  305. considerable experience.
  306.  
  307. Now that we have 12 pointers which can be used like any other
  308. pointer, it is a simple matter to write a loop to allocate a
  309. data block dynamically for each and to fill the respective
  310. fields with any data desirable.  In this case, the fields are
  311. filled with simple data for illustrative purposes, but we
  312. could be reading in a database, readings from some test
  313. equipment, or any other source of data.
  314.  
  315. A few fields are randomly picked in lines 23 through 25 to
  316. receive other data to illustrate that simple assignments can
  317. be used, and the data is printed out to the monitor.  The
  318. pointer point is used in the printout loop only to serve as
  319. an illustration, the data could have been easily printed using
  320. the pet[n] means of definition.  Finally, all 12 blocks of
  321. data are freed before terminating the program.
  322.  
  323. Compile and run this program to aid in understanding this
  324. technique.  As stated earlier, there was nothing new here
  325. about dynamic allocation, only about an array of pointers.
  326.  
  327.  
  328. A LINKED LIST
  329. ____________________________________________________________
  330.  
  331. We finally come to the grandaddy of all         =============
  332. programming techniques as far as being            DYNLINK.C
  333. intimidating.  Load the program DYNLINK.C for   =============
  334. an example of a dynamically allocated linked
  335. list.  It sounds terrible, but after a little
  336. time spent with it, you will see that it is simply another
  337. programming technique made up of simple components that can
  338. be a powerful tool.
  339.  
  340. In order to set your mind at ease, consider the linked list
  341. you used when you were a child.  Your sister gave you your
  342. birthday present, and when you opened it, you found a note
  343. that said, "Look in the hall closet."  You went to the hall
  344. closet, and found another note that said, "Look behind the TV
  345. set."  Behind the TV you found another note that said, "Look
  346. under the coffee pot."  You continued this search, and finally
  347. you found your pair of socks under the dogs feeding dish. 
  348. What you actually did was to execute a linked list, the
  349. starting point being the wrapped present and the ending point
  350. being under the dogs feeding dish.  The list ended at the dogs
  351. feeding dish since there were no more notes.
  352.  
  353.  
  354.                                                     Page 12-6
  355.  
  356.                               Chapter 12 - Dynamic Allocation
  357.  
  358. In the program DYNLINK.C, we will be doing the same thing your
  359. sister forced you to do.  However, we will do it much faster
  360. and we will leave a little pile of data at each of the
  361. intermediate points along the way.  We will also have the
  362. capability to return to the beginning and traverse the entire
  363. list again and again if we so desire.
  364.  
  365.  
  366. THE DATA DEFINITIONS
  367. ____________________________________________________________
  368.  
  369. This program starts similarly to the last two with the
  370. addition of the definition of a constant to be used later. 
  371. The structure is nearly the same as that used in the last two
  372. programs except for the addition of another field within the
  373. structure in line 13, the pointer.  This pointer is a pointer
  374. to another structure of this same type and will be used to
  375. point to the next structure in order.  To continue the above
  376. analogy, this pointer will point to the next note, which in
  377. turn will contain a pointer to the next note after that.
  378.  
  379. We define three pointers to this structure for use in the
  380. program, and one integer to be used as a counter, and we are
  381. ready to begin using the defined structure for whatever
  382. purpose we desire.  In this case, we will once again generate
  383. nonsense data for illustrative purposes.
  384.  
  385.  
  386. THE FIRST FIELD
  387. ____________________________________________________________
  388.  
  389. Using the malloc() function, we request a block of storage on
  390. the heap and fill it with data.  The additional field in this
  391. example, the pointer, is assigned the value of NULL, which is
  392. only used to indicate that this is the end of the list.  We
  393. will leave the pointer named start pointing at this structure,
  394. so that it will always point to the first structure of the
  395. list.  We also assign prior the value of start for reasons we
  396. will see soon.  Keep in mind that the end points of a linked
  397. list will always have to be handled differently than those in
  398. the middle of a list.  We have a single element of our list
  399. now and it is filled with representative data.  Figure 12-5
  400. is the graphical representation of the data space following
  401. execution of line 24.
  402.  
  403.  
  404. FILLING ADDITIONAL STRUCTURES
  405. ____________________________________________________________
  406.  
  407. The next group of assignments and control statements are
  408. included within a for loop so we can build our list fast once
  409. it is defined.  We will go through the loop a number of times
  410. equal to the constant RECORDS defined at the beginning of our
  411. program.  Each time through, we allocate memory, fill the
  412.  
  413.                                                     Page 12-7
  414.  
  415.                               Chapter 12 - Dynamic Allocation
  416.  
  417. first three fields with nonsense, and fill the pointers.  The
  418. pointer in the last record is given the address of this new
  419. record because the prior pointer is pointing to the prior
  420. record.  Thus prior->next is given the address of the new
  421. record we have just filled.  The pointer in the new record is
  422. assigned the value NULL, and the pointer prior is given the
  423. address of this new record because the next time we create a
  424. record, this one will be the prior one at that time.  That may
  425. sound confusing but it really does make sense if you spend
  426. some time studying it.
  427.  
  428. Figure 12-6 illustrates the data space following execution of
  429. the loop two times.  The list is growing downward by one
  430. element each time we execute the statements in the loop.  When
  431. we have gone through the for loop 6 times, we will have a list
  432. of 7 structures including the one we generated prior to the
  433. loop.  The list will have the following characteristics.
  434.  
  435. 1.   The pointer named start points to the first structure in
  436.      the list.
  437.  
  438. 2.   Each structure contains a pointer to the next structure.
  439.  
  440. 3.   The last structure has a pointer containing the value
  441.      NULL and can be used to detect the end.
  442.  
  443. It should be clear to you, if you understand the overall data
  444. structure, that it is not possible to simply jump into the
  445. middle of the list and change a few values.  The only way to
  446. get to the third structure is by starting at the beginning and
  447. working your way down through the list one record at a time. 
  448. Although this may seem like a large price to pay for the
  449. convenience of putting so much data outside of the program
  450. area, it is actually a very good way to store some kinds of
  451. data.
  452.  
  453. A word processor would be a good application for this type of
  454. data structure because you would never need to have random
  455. access to the data.  In actual practice, this is the basic
  456. type of storage used for the text in a word processor with
  457. one line of text per record.  Actually, a program with any
  458. degree of sophistication would use a doubly linked list.  This
  459. would be a list with two pointers per record, one pointing
  460. down to the next record, and the other pointing up to the
  461. record just prior to the one in question.  Using this kind of
  462. a record structure would allow traversing the data in either
  463. direction.
  464.  
  465.  
  466. PRINTING THE DATA OUT
  467. ____________________________________________________________
  468.  
  469. To print the data out, a similar method is used as that used
  470. to generate the data.  The pointers are initialized and are
  471.  
  472.                                                     Page 12-8
  473.  
  474.                               Chapter 12 - Dynamic Allocation
  475.  
  476. then used to go from record to record reading and displaying
  477. each record one at a time.  Printing is terminated when the
  478. NULL in the last record is found, so the program doesn't even
  479. need to know how many records are in the list.  Finally, the
  480. entire list is deleted to make room in memory for any
  481. additional data that may be needed, in this case, none.  Care
  482. must be taken to assure that the last record is not deleted
  483. before the NULL is checked.  Once the data is gone, it is
  484. impossible to know if you are finished yet.
  485.  
  486.  
  487. MORE ABOUT DYNAMIC ALLOCATION AND LINKED LISTS
  488. ____________________________________________________________
  489.  
  490. It is not difficult, nor is it trivial, to add elements into
  491. the middle of a linked list.  It is necessary to create the
  492. new record, fill it with data, and point its pointer to the
  493. record it is desired to precede.  If the new record is to be
  494. installed between the 3rd and 4th, for example, it is
  495. necessary for the new record to point to the 4th record, and
  496. the pointer in the 3rd record must point to the new one. 
  497. Adding a new record to the beginning or end of a list are each
  498. special cases.  Consider what must be done to add a new record
  499. in a doubly linked list. 
  500.  
  501. Entire books are written describing different types of linked
  502. lists and how to use them, so no further detail will be given. 
  503. The amount of detail given should be sufficient for a
  504. beginning understanding of C and its capabilities.
  505.  
  506.  
  507. ANOTHER NEW FUNCTION - calloc()
  508. ____________________________________________________________
  509.  
  510. One more function must be mentioned, the calloc() function. 
  511. This function allocates a block of memory and clears it to all
  512. zeros which may be useful in some circumstances.  It is
  513. similar to malloc and will be left as an exercise for you to
  514. read about and use calloc() if you desire.
  515.  
  516.  
  517. PROGRAMMING EXERCISES
  518. ____________________________________________________________
  519.  
  520. 1.   Rewrite the example program STRUCT1.C from chapter 11 to
  521.      dynamically allocate the two structures.
  522.  
  523. 2.   Rewrite the example program STRUCT2.C from chapter 11 to
  524.      dynamically allocate the 12 structures.
  525.  
  526.  
  527.  
  528.  
  529.                                                     Page 12-9
  530.